package com.ruoyi.collect.hydrology.service;

import com.ruoyi.collect.hydrology.model.FileDto;
import com.ruoyi.collect.hydrology.util.FileUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
public class CollectFileReader {
    protected static final int BATCH_COLLECT_LIMIT = Integer.MAX_VALUE;
    private final String dir;

    public CollectFileReader(String hydrology) {
        this.dir = hydrology;
    }

    public List<FileDto> getFiles() {

        File[] files = new File(dir).listFiles();
        if (files == null) {
            log.info("null_dir: [{}]", dir);
            return Collections.emptyList();
        }
        log.info("file_count: [{}]", files.length);
        List<File> toSort = new ArrayList<>();
        for (File f : files) {
            if (f.isFile()) {
                if (f.exists()) {
                        toSort.add(f);
                } else {
                    log.warn("not_exist: [{}]", f.getAbsolutePath());
                }
            } else {
                log.warn("not_file: [{}]", f.getAbsolutePath());
            }
        }
//        toSort.sort(Comparator.comparing(f -> {
//            String[] s = f.getName().split("_");
//            return s[s.length - 1];
//        }));
        List<FileDto> list = new ArrayList<>();
        long limit = BATCH_COLLECT_LIMIT;
        for (File f : toSort) {
            FileDto collectFileInfo = toCollectFileInfo(f, true);
            if (collectFileInfo != null) {
                list.add(collectFileInfo);
                if (limit-- == 0) break;
            } else {
                log.warn("not_collect: [{}]", f.getAbsolutePath());
            }
        }
        log.info("list_count: [{}]", list.size());
        return list;
    }

    private FileDto toCollectFileInfo(final File file, final boolean getContent) {

        if (file.length() > Integer.MAX_VALUE) {
            boolean delete = delete(file.getAbsolutePath());
            log.warn("too_big_file[{}]: [{}]", delete, file);
            return null;
        }
        try {
            FileDto collectFileInfo = new FileDto();
            collectFileInfo.setDir(dir);
            collectFileInfo.setPath(file.getAbsolutePath());
            collectFileInfo.setFileName(file.getName());
            if (!getContent) {
                return collectFileInfo;
            }

//            collectFileInfo.setMd5(Md5Util.md5Hex(new FileInputStream(file)));
            collectFileInfo.setBytes(FileUtil.readBytes(new FileInputStream(file)));
            if (collectFileInfo.getBytes() == null || collectFileInfo.getBytes().length < 2) {
//                invalidFile(collectFileInfo);
                return null;
            }
            byte lastByte = collectFileInfo.getBytes()[collectFileInfo.getBytes().length - 2];
//            if (lastByte != (byte) 124) {
//                invalidFile(collectFileInfo);
//                return null;
//            }
            return collectFileInfo;
        } catch (Exception e) {
            log.warn("exception: " + file, e);
            return null;
        }
    }

    private boolean delete(String filePath) {
        for (int i = 0; i < 4; i++) {
            boolean delete = new File(filePath).delete();
            if (delete) {
                return true;
            }
            System.gc();
            log.warn("delete_count:[{}]", i);
        }
        return false;
    }
}
